package domain.stack;

import java.util.concurrent.atomic.AtomicReference;

import control.Experimentor;

public class ConcurrentStack <E> extends AbstractConcurrentStack<E> {
    
	private AtomicReference<Node<E>> top = new AtomicReference<Node<E>>();

    /* (non-Javadoc)
	 * @see domain.ConcurrentStackInterface#push(E)
	 */
    public void push(E item) {
        Node<E> newHead = new Node<E>(item);
        Node<E> oldHead;
        do {
        	Experimentor.sum++;// TODO remove
            oldHead = top.get();
            newHead.next = oldHead;
        } while (!top.compareAndSet(oldHead, newHead));
    }

    /* (non-Javadoc)
	 * @see domain.ConcurrentStackInterface#pop()
	 */
    public E pop() {
        Node<E> oldHead;
        Node<E> newHead;
        do {
        	Experimentor.sum++;// TODO remove
            oldHead = top.get();
            if (oldHead == null)
                return null;
            newHead = oldHead.next;
        } while (!top.compareAndSet(oldHead, newHead));
        return oldHead.item;
    }
}
